package com.database;

import java.sql.Blob;
import java.sql.Clob;
import java.sql.Connection;
import java.sql.Date;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Time;
import java.sql.Timestamp;
import java.sql.Types;
import java.util.ArrayList;
import java.util.Iterator;

import sun.jdbc.rowset.CachedRowSet;

import com.commutils.RefUtils;

/**
 * <p>Description:* 实现复杂的多表查询的情况。这个类<br>
 *    只有查找方法。在查找以前要把整条SQL语句作为参数，<br>
 *    调用setSqlSelect方法。用setParam方法设置SQL<br>
 *    语句的参数。</p>
 * <p>Title:QueryBPO </p>
 * 调用实例：
 * CachedRowSet crs1 = new CachedRowSet();
 * 第一种处理方式：
 * String sql="select * from table a where a.id='23'";
 * crs1 = SqlQuery.findAll(conn,sql,null);
 * 或第二种处理方式：
 * String sql="select * from table a where a.id=? and a.name=?";
 * ArrayList paramssqjz1 = new ArrayList();
 * int id=1234;
 * String name="swrwkdjd";
 * paramssqjz1.add(0,id);
 * paramssqjz1.add(1,name);
 * crs1=SqlQuery(con,sql,paramssqjz1);
 * @author kevin
 * @Date 2009-3-13
 * @version 1.0
 */


public class SqlQuery {

    public SqlQuery() {
    }


    /**
     * 查询方法。查询满足strSql条件的数据项。该方法会将捕获到的异常封
     * @param con:Connection - 与数据库的连接
     * @param strSql:String - 将要执行的SQL查询语句；
     * @param sqlParams : ArrayList － java.util.ArrayList 类型的属性，该属性
     * 用来存放将要执行的SQL语句中的参数（即，所有“？”的值）。sqlParams中封装了所有的
     * 参数，他们按照在SQL语句中出现的先后顺序被封装在ArrayList中。
     * @return CachedRowSet - 得到的结果
     */
    public static CachedRowSet findAll(Connection con, String strSql,
                                       ArrayList<Object> sqlParams) {

        PreparedStatement ps = null;
        ResultSet rs = null;
        try {
            CachedRowSet rowSet;
            ps = preparedStatementCreate(con, strSql,
                                         sqlParams); //生成preparedStatement 实例
            rs = ps.executeQuery(); //执行查询操作

            rowSet = new CachedRowSet(); //生成一个CachedRowSet对象
            rowSet.populate(rs); //   将查询结果加入到rowSet 实例中

            return rowSet;
        } catch (SQLException ex) {
            //LogWritter.sysError("00051",ex);
            try {
                if(con!=null)
                con.close();
            } catch (SQLException ex2) {
            }
            ex.printStackTrace();
            return null;
        } catch (Exception exother) {
            //LogWritter.sysError("00052",exother);
            try {
                if(con!=null)
                con.close();
            } catch (SQLException ex2) {
            }
            exother.printStackTrace();
            return null;
        } finally {
            try {
                if (rs != null) {
                    rs.close(); //   关闭结果集
                }

                if (ps != null) {
                    ps.close(); //   关闭preparedStatement对象
                }
//                if (con != null) {
//                    con.close();
//                }
            } catch (SQLException ex1) {
                //LogWritter.sysError(ex1.getMessage() , ex1) ;
                ex1.printStackTrace();
            }
        }
    }
 //分页操作，指定要取的分页起始页和结束页及要查询的sql语句

    public static CachedRowSet findAllPrePage(Connection con, String strSql,
                                       int firstResult,int maxResults) {
        String presql=getPaginationSql(strSql,firstResult,maxResults);
        return findAll(con,presql,null);
    }
    private static String getPaginationSql(String sql,int firstResult,int maxResults){
            StringBuffer paginationSql=new StringBuffer("");
            paginationSql.append("select * from ( select row_.*, rownum rownum_ from ( ");
            paginationSql.append(sql);
            paginationSql.append(" ) row_ where rownum < ").append(firstResult+maxResults);
            paginationSql.append(") where rownum_ >= ").append(firstResult);
            
            return paginationSql.toString();
	}

    /**
     * 生成PreparedStatement实例，然后为PreparedStatement<br>
     * 实例添加属性（data中传递进来的）。最后返回PreparedStatement<br>
     * 实例。PreparedStatement由参数con生成。PreparedStatement<br>
     * 中需要设置的参数由sqlParam给出。方法可以根据参数类型将参数转换<br>
     * 为该类型，并调用PreparedStatement中相应的setＸＸＸ方法设置参<br>
     * 数。

     * @param  con:Connection 与数据库建立的连接

     * @param  sqlStr:String 将要执行的sql语句
     * @param  sqlParams:ArrayList SQL语句中的参数（“?”）
     * @return PreparedStatement 生成的PreparedStatement实例
     * @throws SQLException
     */
    private static PreparedStatement preparedStatementCreate
            (Connection con, String sqlStr, ArrayList<Object> sqlParams) throws
            SQLException {
        PreparedStatement ps = con.prepareStatement(sqlStr); //生成preparedStatement实例

        if (sqlParams == null) {
            return ps;
//            sqlParams = new ArrayList() ;
        }
        Iterator<Object> ii = sqlParams.iterator();
        int i = 1;

        while (ii.hasNext()) {
            // 判断各个参数的类型，并调用相应的setter方法；

            Object value = ii.next();
            String type = RefUtils.getDataType(value);
            if (type == null) {
                ps.setNull(i++, Types.CHAR);
            } else if (type.equals("String")) {
                ps.setString(i++, (String) value);
            } else if (type.equals("Long")) {
                ps.setLong(i++, ((Long) value).longValue());
            } else if (type.equals("Integer")) {
                ps.setInt(i++, ((Integer) value).intValue());
            } else if (type.equals("Double")) {
                ps.setDouble(i++, ((Double) value).doubleValue());
            } else if (type.equals("Date")) {
                ps.setDate(i++, ((Date) value));
            } else if (type.equals("Boolean")) {
                ps.setBoolean(i++, ((Boolean) value).booleanValue());
            } else if (type.equals("Short")) {
                ps.setShort(i++, ((Short) value).shortValue());
            } else if (type.equals("Time")) {
                ps.setTime(i++, ((Time) value));
            } else if (type.equals("Timestamp")) {
                ps.setTimestamp(i++, ((Timestamp) value));
            } else if (type.equals("Float")) {
                ps.setFloat(i++, ((Float) value).floatValue());
            } else if (type.equals("Blob")) {
                ps.setBlob(i++, ((Blob) value));
            } else if (type.equals("Clob")) {
                ps.setClob(i++, ((Clob) value));
            } else {
                ps.setObject(i++, value);
            }

        }

        return ps;

    }


    public static void main(String[] args) throws Exception {
//        Connection con = DBConnection.getConnection();
//        findAll("dSQL_KT42cxqdxxxx",con,null);
//        List cc = new ArrayList();
//        cc.add("11");
    }


}
